﻿Imports FairShop.TellingDataSet
Imports System
Imports System.ComponentModel
Imports System.IO
Imports System.Linq
Imports System.Windows.Forms

Public Class TellingForm

    Enum SoortTelling
        Begin
        Einde
    End Enum

    Private _soort As SoortTelling
    Private _first As Boolean = True
    Private _timer As Timer
    Private _chequesWerdenDoorlopen As Boolean = False
    'Private _tenminsteEenmaalBewaard As Boolean = False

#Region "Public properties"

    Private _totaal As Decimal = 0
    ''' <summary>
    ''' Totale waarde van de telling in Euro
    ''' </summary>
    Public Property Totaal() As Decimal
        Get
            Return _totaal
        End Get
        Set(ByVal value As Decimal)
            _totaal = value
            If (value <> VerwachtBedrag) Then
                lblTotaal.ForeColor = Color.Red
                lblSaldo.ForeColor = Color.Red
            Else
                lblTotaal.ForeColor = SystemColors.ControlText
                lblSaldo.ForeColor = SystemColors.ControlText
            End If
            lblTotaal.Text = value.ToString("c")
            lblSaldo.Text = (Totaal - VerwachtBedrag).ToString("c")
        End Set
    End Property

    Private _verwachtBedrag As Decimal
    ''' <summary>
    ''' Verwachte waarde van de telling in Euro
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    Public Property VerwachtBedrag() As Decimal
        Get
            Return _verwachtBedrag
        End Get
        Set(ByVal value As Decimal)
            _verwachtBedrag = value
            lblVerwacht.Text = value.ToString("c")
            lblSaldo.Text = (Totaal - VerwachtBedrag).ToString("c")
        End Set
    End Property

    Public Property Opmerkingen() As String
        Get
            Return tbOpmerkingen.Text
        End Get
        Set(ByVal value As String)
            tbOpmerkingen.Text = value
        End Set
    End Property

    Public ReadOnly Property TellingTabel() As TellingDataSet.LaatsteTellingDataTable
        Get
            Return Me.TellingDataSet.LaatsteTelling
        End Get
    End Property

#End Region

#Region "Constructor"

    Public Sub New(ByVal verwacht As Decimal, ByVal soort As SoortTelling)
        Me.InitializeComponent()
        InitGrid()
        VerwachtBedrag = verwacht
        _soort = soort
    End Sub

    Protected Overrides Sub OnLoad(ByVal e As EventArgs)
        MyBase.OnLoad(e)
        Me.LaatsteTellingTableAdapter.Fill(Me.TellingDataSet.LaatsteTelling)
        ' zet focus op eerste aantal in te vullen
        'Me.LaatsteTellingBindingSource.Position = 0
        Grid1.CurrentCell = Grid1.Item(0, 0)
        HerberekenTotaal()
        _first = False
        If (Utility.IsOefenVersie()) Then
            Me.BackColor = Utility.GetOefenVersieColor()
        End If
    End Sub

#End Region

#Region "Event handling"

    Protected Overrides Sub OnKeyUp(ByVal e As System.Windows.Forms.KeyEventArgs)
        MyBase.OnKeyUp(e)
        Select Case e.KeyCode
            Case Keys.F12
                ' hier gebeurt "Annuleren" niet met Esc omdat het venster een grid bevat,
                ' en daar willen we met Esc de huidige ingave kunnen ongedaan maken.
                Me.DialogResult = DialogResult.Cancel
                Me.Close()
            Case Keys.F2
                If (Not btnOK.Enabled) Then Return
                Me.btnOK_Click(Me, EventArgs.Empty)
        End Select
    End Sub

    Private Sub Grid1_DataError(ByVal sender As Object, ByVal e As DataGridViewDataErrorEventArgs) Handles Grid1.DataError
        MsgBox.ShowError("De ingevoerde gegevens zijn niet geldig. Voer alleen gehele getallen in.")
    End Sub

    ' nodig omdat je anders soms twee keer F2 moet klikken vooraleer het formulier sluit
    Private Sub Grid1_PreviewKeyDown(ByVal sender As System.Object, ByVal e As PreviewKeyDownEventArgs) Handles Grid1.PreviewKeyDown
        Select Case e.KeyCode
            Case Keys.F2
                If (Not btnOK.Enabled) Then Return
                ' Wacht 100ms met de uitvoering tot de F2-key volledig verwerkt is.
                ' Anders gaat de F2-KeyUp ook nog eens naar het aanroepende scherm.
                ' Als dit scherm MainForm is wordt dit TellingForm weer geopend!
                _timer = New Timer()
                _timer.Interval = 300
                AddHandler _timer.Tick, AddressOf Me.TimerHandler
                _timer.Enabled = True
        End Select
    End Sub

    Private Sub TimerHandler(ByVal sender As Object, ByVal e As EventArgs)
        _timer.Enabled = False
        Me.btnOK_Click(Me, EventArgs.Empty)
    End Sub

    Protected Overrides Sub OnFormClosing(ByVal e As FormClosingEventArgs)
        MyBase.OnFormClosing(e)
        'If (Not _tenminsteEenmaalBewaard OrElse TellingDataSet.HasChanges()) Then
        If (TellingDataSet.HasChanges()) Then
            Dim result As DialogResult = MessageBox.Show("Ben je zeker dat je wil annuleren? Als je 'Ja' zegt, gaan alle gemaakte wijzigingen in dit scherm verloren.", _
                    "Bevestiging", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
            Select Case result
                Case DialogResult.Yes
                    Me.DialogResult = DialogResult.Cancel
                Case DialogResult.No
                    e.Cancel = True
            End Select
        End If
    End Sub

    ' gaat al automatisch omdat de knop als DialogResult "Cancel" heeft
    'Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCancel.Click
    '    Me.Close()
    'End Sub

    Private Sub btnOK_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnOK.Click
        'If (Not ValidateChildren()) Then
        If (Not _chequesWerdenDoorlopen) Then
            If (MessageBox.Show("Heb je de cheques ook nageteld?", "Cheques", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No) Then
                _chequesWerdenDoorlopen = True ' boodschap maar 1 keer tonen
                Return
            End If
        End If
        If (Opmerkingen = "" AndAlso Totaal <> VerwachtBedrag) Then
            MsgBox.ShowError("De totalen kloppen niet. Leg onder ""Opmerkingen"" uit wat je verklaring is.")
            tbOpmerkingen.Focus()
            Return
        End If
        If BewaarWijzigingen() Then
            Me.DialogResult = DialogResult.OK
            Me.Close()
        End If
    End Sub

    Private Sub Grid1_CellValidated(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles Grid1.CellValidated
        Me.btnOK.Enabled = False
        Dim succes As Boolean = HerberekenTotaal()
        Me.btnOK.Enabled = succes
    End Sub

    Private Sub tbOpmerkingen_Validating(ByVal sender As System.Object, ByVal e As CancelEventArgs) Handles tbOpmerkingen.Validating
        ' als de telling niet klopt, moet je een opmerking invullen
        If (Opmerkingen = "" AndAlso Totaal <> VerwachtBedrag) Then
            Me.ErrorProvider1.SetError(tbOpmerkingen, "Opmerking verplicht als de telling niet klopt")
            ' e.Cancel = True  ' niet goed: dan wordt de cursor "gegijzeld" in het opmerkingenvak tot je iets invult
        End If
    End Sub

    Protected Sub Grid1_OnCellEnter(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles Grid1.CellEnter
        ' Zorg ervoor dat je bij het tabben door de cellen de read-only cellen overslaat
        If (Grid1.Rows(e.RowIndex).Cells(e.ColumnIndex).ReadOnly AndAlso Not _first) Then
            SendKeys.Send("{TAB}")
        End If
        If (_first) Then _first = False
        If (Grid1.Rows(e.RowIndex).Cells(0).Value.ToString().StartsWith("Cheque")) Then
            _chequesWerdenDoorlopen = True
        End If
    End Sub

#End Region

#Region "Helperfuncties"

    Private Sub InitGrid()
        With DataGridViewHelper.GetGridColumnByDataName(Me.TellingDataSet.LaatsteTelling.OmschrijvingColumn.ColumnName, Grid1)
            .Width = 150
            .ReadOnly = True
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Me.TellingDataSet.LaatsteTelling.AantalColumn.ColumnName, Grid1)
            .Width = 100
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
        End With
    End Sub

    Private Function HerberekenTotaal() As Boolean
        Totaal = 0
        For Each row As TellingDataSet.LaatsteTellingRow In Me.TellingDataSet.LaatsteTelling.Rows
            If (row.IsAantalNull()) Then
                MsgBox.ShowError("Gelieve een getal in te vullen!")
                Return False
            End If
            row.Totaal = row.Aantal * row.Waarde
            Totaal += row.Aantal * row.Waarde
        Next
        Return True
    End Function

    Private Function BewaarWijzigingen() As Boolean
        Me.Validate()
        If (Me.TellingDataSet.LaatsteTelling.AsEnumerable().Any(Function(row As LaatsteTellingRow) row.IsAantalNull())) Then
            Return False
        End If
        Me.LaatsteTellingBindingSource.EndEdit()
        Me.LaatsteTellingTableAdapter.Update(Me.TellingDataSet)
        '_tenminsteEenmaalBewaard = True
        LogLaatsteTelling()
        Return True
    End Function

    Private Sub LogLaatsteTelling()
        Dim infoSoort As String = "begin van de winkelbeurt"
        If (_soort = SoortTelling.Einde) Then infoSoort = "eind van de winkelbeurt"
        log.LogLaatsteTelling(infoSoort, TellingDataSet, Totaal)
    End Sub

#End Region

End Class